package jwcb.javapjframework.ms_template.service.service;

import jwcb.javapjframework.common.redis.RedisService.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class RedisBasicTestService {

    @Autowired
    private RedisService redisService;

    private static final String TEST_KEY = "test:basic:operations";
    private static final String TEST_KEY2 = "test:basic:operations2";
    private static final String TEST_KEY3 = "test:basic:operations3";
    private static final String TEST_VALUE = "Hello Redis";

    public String testRedisBasicOperations() {
        StringBuilder result = new StringBuilder();
        result.append("Redis 基本操作测试开始...\n\n");
        
        try {
            // 清理可能存在的旧数据
            redisService.deleteObject(TEST_KEY);
            redisService.deleteObject(TEST_KEY2);
            redisService.deleteObject(TEST_KEY3);
            
            // 1. 设置值并验证存在性
            redisService.setCacheObject(TEST_KEY, TEST_VALUE);
            Boolean exists = redisService.hasKey(TEST_KEY);
            result.append("测试1: 设置值和存在性检查\n")
                  .append("预期: true, 实际: ").append(exists).append("\n")
                  .append("结果: ").append(Boolean.TRUE.equals(exists) ? "成功" : "失败").append("\n\n");
            
            // 2. 设置过期时间（默认秒）
            redisService.expire(TEST_KEY, 10);
            long expireTime = redisService.getExpire(TEST_KEY);
            result.append("测试2: 设置过期时间(默认秒)\n")
                  .append("预期: 10秒左右, 实际: ").append(expireTime).append("秒\n")
                  .append("结果: ").append(expireTime > 0 && expireTime <= 10 ? "成功" : "失败").append("\n\n");
            
            // 3. 设置过期时间（指定时间单位）
            redisService.expire(TEST_KEY, 500, TimeUnit.MILLISECONDS);
            long expireTimeMs = redisService.getExpire(TEST_KEY);
            result.append("测试3: 设置过期时间(指定毫秒)\n")
                  .append("预期: 500毫秒左右, 实际: ").append(expireTimeMs).append("毫秒\n")
                  .append("结果: ").append(expireTimeMs > 0 && expireTimeMs <= 500 ? "成功" : "失败").append("\n\n");
            
            // 4. 重命名键
            redisService.renameKey(TEST_KEY, TEST_KEY2);
            Boolean oldExists = redisService.hasKey(TEST_KEY);
            Boolean newExists = redisService.hasKey(TEST_KEY2);
            String value = redisService.getCacheObject(TEST_KEY2,String.class);
            result.append("测试4: 重命名键\n")
                  .append("预期: 旧键不存在, 新键存在且值相同, 实际: ")
                  .append("旧键存在: ").append(oldExists).append(", ")
                  .append("新键存在: ").append(newExists).append(", ")
                  .append("值: ").append(value).append("\n")
                  .append("结果: ").append(Boolean.FALSE.equals(oldExists) && 
                         Boolean.TRUE.equals(newExists) && 
                         TEST_VALUE.equals(value) ? "成功" : "失败").append("\n\n");
            
            // 5. 键模式查找
            redisService.setCacheObject(TEST_KEY3, "Pattern Test");
            Collection<String> keys = redisService.keys("test:basic:*");
            result.append("测试5: 键模式查找\n")
                  .append("预期: 包含test:basic:operations2和test:basic:operations3, 实际: ").append(keys).append("\n")
                  .append("结果: ").append(keys != null && keys.contains(TEST_KEY2) && 
                         keys.contains(TEST_KEY3) ? "成功" : "失败").append("\n\n");
            
            // 6. 删除单个对象
            boolean deleteResult = redisService.deleteObject(TEST_KEY2);
            Boolean afterDelete = redisService.hasKey(TEST_KEY2);
            result.append("测试6: 删除单个对象\n")
                  .append("预期: 删除成功且键不存在, 实际: ")
                  .append("删除结果: ").append(deleteResult).append(", ")
                  .append("删除后存在: ").append(afterDelete).append("\n")
                  .append("结果: ").append(deleteResult && Boolean.FALSE.equals(afterDelete) ? "成功" : "失败").append("\n\n");
            
            // 7. 删除多个对象
            List<String> keysToDelete = new ArrayList<>();
            keysToDelete.add(TEST_KEY3);
            
            // 添加一些额外的测试键
            for (int i = 1; i <= 3; i++) {
                String key = "test:basic:extra" + i;
                redisService.setCacheObject(key, "Extra Value " + i);
                keysToDelete.add(key);
            }
            
            boolean multiDeleteResult = redisService.deleteObject(keysToDelete);
            Boolean allDeleted = true;
            for (String key : keysToDelete) {
                if (redisService.hasKey(key)) {
                    allDeleted = false;
                    break;
                }
            }
            
            result.append("测试7: 删除多个对象\n")
                  .append("预期: 删除成功且所有键不存在, 实际: ")
                  .append("删除结果: ").append(multiDeleteResult).append(", ")
                  .append("所有键不存在: ").append(allDeleted).append("\n")
                  .append("结果: ").append(multiDeleteResult && allDeleted ? "成功" : "失败").append("\n\n");
            
            // 8. 过期键自动删除验证
            redisService.setCacheObject(TEST_KEY, "Expiration Test");
            redisService.expire(TEST_KEY, 1, TimeUnit.SECONDS);
            
            // 等待1.2秒确保过期
            Thread.sleep(1200);
            
            Boolean expired = redisService.hasKey(TEST_KEY);
            result.append("测试8: 过期键自动删除\n")
                  .append("预期: false, 实际: ").append(expired).append("\n")
                  .append("结果: ").append(Boolean.FALSE.equals(expired) ? "成功" : "失败").append("\n\n");
            
            result.append("✅ 所有基本操作测试完成!");
            
        } catch (Exception e) {
            result.append("\n❌ 测试异常: ").append(e.getMessage());
            e.printStackTrace();
        } finally {
            // 清理测试数据
            redisService.deleteObject(TEST_KEY);
            redisService.deleteObject(TEST_KEY2);
            redisService.deleteObject(TEST_KEY3);
            // 清理额外创建的键
            for (int i = 1; i <= 3; i++) {
                redisService.deleteObject("test:basic:extra" + i);
            }
        }
        
        return result.toString();
    }
}